#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h> 
#include <stdlib.h>       
#include <string.h>
#include <pthread.h>
//#include <sys/sem.h>
#include <errno.h>
#include <sys/ipc.h>
//#include <sys/msg.h>
#include <sys/timeb.h>
#include <sys/socket.h>
//#include <sys/socketvar.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <semaphore.h>
#include <string.h>
#include <termios.h>
#include <linux/input.h>
#include <semaphore.h>
#include <linux/shm.h>
#include <asm/unistd.h>
#include <sys/poll.h>

#include "common.h"

//protoSlaveType
enum _protoSlaveType
{
		_openOutSys		= 0x00,
		_closeOutSys	= 0x01,
		
		_setDeviceName = 0x02,
		_getDeviceName = 0x03,
		
		_getOutSysOpenStatus = 0x04,
		
		_setProjectorVgaMode = 0x05,
		_setProjectorHdmiMode = 0x06,
		
		_ctrlProjector = 0x07,
};

static int openOutSys(struct recvData *recvData, struct packageFilter *pFilter);
static int closeOutSys(struct recvData *recvData, struct packageFilter *pFilter);

static int setDeviceName(struct recvData *recvData, struct packageFilter *pFilter);
static int getDeviceName(struct recvData *recvData, struct packageFilter *pFilter);

static int getOutSysOpenStatus(struct recvData *recvData, struct packageFilter *pFilter);

static int setProjectorVgaMode(struct recvData *recvData, struct packageFilter *pFilter);
static int setProjectorHdmiMode(struct recvData *recvData, struct packageFilter *pFilter);

static int ctrlProjector(struct recvData *recvData, struct packageFilter *pFilter);

extern SystemParam *pgSystemParam;

void ctrlOutSysServer(struct recvData *recvData)
{
		printf("into ctrlOutSysServer\n");
		if(recvData == NULL)
		{
				printf("recvData == NULL ! {%s(%d)}\n",__FILE__,__LINE__);
				return;	
		}
	
		struct packageFilter filter;
		int ret = explainPackageHead(recvData, &filter);
		if(ret < 0)
		{
				printf("explainPackageHead fail ! {%s,%d}\n", __FILE__, __LINE__);
				return;	
		}
		
		switch(filter.protoSlaveType)
		{
				case _openOutSys:
				{
						openOutSys(recvData, &filter);	
						break;	
				}
				case _closeOutSys:
				{
						closeOutSys(recvData, &filter);	
						break;
				}
				case _setDeviceName:
				{
						setDeviceName(recvData, &filter);	
						break;
				}
				case _getDeviceName:
				{
						getDeviceName(recvData, &filter);	
						break;
				}
				case _getOutSysOpenStatus:
				{
							getOutSysOpenStatus(recvData, &filter);	
						break;
				}
				case _setProjectorVgaMode:
				{
							setProjectorVgaMode(recvData, &filter);	
						break;
				}
				case _setProjectorHdmiMode:
				{
							setProjectorHdmiMode(recvData, &filter);	
						break;
				}
				case _ctrlProjector:
				{
						ctrlProjector(recvData, &filter);
						break;
				}
				default:
				{
						printf("filter.protoSlaveType not right ! filter.protoSlaveType = %d {%s,%d}\n", filter.protoSlaveType, __FILE__,__LINE__);
						break;	
				}
		}		
}

static int openOutSys(struct recvData *recvData, struct packageFilter *pFilter)
{
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 4)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}	
	
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		
		int ret = cmdOpenOutSys();
		int returnRet = (ret == 0) ? 0 : 1;
		
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		return 0;
}

static int closeOutSys(struct recvData *recvData, struct packageFilter *pFilter)
{
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 4)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}	
	
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		
		int ret = cmdCloseOutSys();
		int returnRet = (ret == 0) ? 0 : 1;
		
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		return 0;
}


static int setDeviceName(struct recvData *recvData, struct packageFilter *pFilter)
{
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen < 5)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}	
	
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		
		char *deviceName = (char *)(pFilter->pData + 4);
		unsigned char deviceNameLen = pFilter->dataLen - 4;
		deviceName[deviceNameLen] = '\0';
	
		int ret = writeOneConfigValue("device_name", deviceName);
		if(ret < 0)
		{
				char logBuf[128];
				sprintf(logBuf, "writeOneConfigValue device_name fail ! deviceName = %s\n", deviceName);
				writeLog(logBuf, __FILE__, __LINE__);
		}
		else
		{
				pthread_mutex_lock(&(pgSystemParam->deviceNameLock));	
				strcpy(pgSystemParam->deviceName, deviceName);
				pthread_mutex_unlock(&(pgSystemParam->deviceNameLock));
		}
		
		int returnRet = (ret == 0) ? 0 : 1;
			
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		
		printf("setDeviceName:deviceNameLen,deviceName,pgSystemParam->deviceName = %d,%s,%s\n", deviceNameLen,deviceName,pgSystemParam->deviceName);
		return 0;
}


static int getDeviceName(struct recvData *recvData, struct packageFilter *pFilter)
{
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 4)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}	
	
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		
		char deviceName[256];
		unsigned char deviceNameLen;

		pthread_mutex_lock(&(pgSystemParam->deviceNameLock));	
		strcpy(deviceName, pgSystemParam->deviceName);
		pthread_mutex_unlock(&(pgSystemParam->deviceNameLock));
		
		deviceNameLen = strlen(deviceName);
		int returnRet = (deviceNameLen > 0) ? 0 : 1;
			
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5 + deviceNameLen;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		memcpy(recvData->buf + headLen + 5, deviceName, deviceNameLen);
		
		printf("getDeviceName:deviceName = %s\n", deviceName);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		return 0;
}

static int getOutSysOpenStatus(struct recvData *recvData, struct packageFilter *pFilter)
{
		printf("getOutSysOpenStatus\n");
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 4)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}	
	
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
	
		unsigned char  returnRet = (pgSystemParam->outSysIsOpen) ? 1 : 0;
			
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		
		printf("getOutSysOpenStatus:returnRet = %d\n", returnRet);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		return 0;
			
}


static int setProjectorVgaMode(struct recvData *recvData, struct packageFilter *pFilter)
{
		printf("setProjectorVgaMode\n");
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 4)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}	
	
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		
		setProjectVga();
		int ret = 0;
		int returnRet = (ret == 0) ? 0 : 1;
			
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		
		printf("setProjectorVgaMode:returnRet = %d\n", returnRet);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		return 0;
}


static int setProjectorHdmiMode(struct recvData *recvData, struct packageFilter *pFilter)
{
		printf("setProjectorHdmiMode\n");
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 4)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}	
	
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		
		setProjectHdmi();
		int ret = 0;
		int returnRet = (ret == 0) ? 0 : 1;
			
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 
		
		printf("setProjectorHdmiMode:returnRet = %d\n", returnRet);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		return 0;
}

static int ctrlProjector(struct recvData *recvData, struct packageFilter *pFilter)
{
		printf("into ctrlProjector\n");
		if(pFilter->dataDirection != 0x00)	
		{
				printf("proto %d,%d pFilter->dataDirection error ! pFilter->dataDirection = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataDirection);
				return -1;	
		}
		
		if(pFilter->dataLen != 5)
		{
				printf("proto %d,%d pFilter->dataLen error ! pFilter->dataLen = %d\n", pFilter->protoMasterType, pFilter->protoSlaveType, pFilter->dataLen);
				return -2;	
		}
	
		if(&(recvData->addr) == NULL)
		{
				printf("recvData->addr == NULL ! index=%d, {%s,%d}\n", index, __FILE__, __LINE__);
				return -3;	
		}	
	
		unsigned char privateData[4];
		memcpy(privateData, pFilter->pData, 4);
		unsigned char act = pFilter->pData[4];
		
		int ret = 0;
		if(act > 1)
		{
				char logBuf[128];
				sprintf(logBuf, "ctrlProjector: act is unknow ! act = %d\n", act);
				writeLog(logBuf, __FILE__, __LINE__);
				ret = -99;
		}
		else
		{
				
		}
		
		int returnRet = (ret == 0) ? 0 : 1;
			
		unsigned char dataDirection = 0x01;
		unsigned char dataLen = 5;
		unsigned int headLen = recvData->count - pFilter->dataLen;
		unsigned int packageSize = headLen + dataLen;
		createProtoCombinationData(recvData->buf + 3, pFilter->deviceType, dataDirection, pFilter->communicationWay, dataLen);
		
		unsigned char checkCode = 0;
		for(unsigned char i=0; i < headLen-1; i++)
		{
				checkCode += recvData->buf[i];
		}
		recvData->buf[headLen - 1] = checkCode;
		
		memcpy(recvData->buf + headLen, privateData, 4);
		recvData->buf[headLen + 4] = returnRet; 	
		
		printf("ctrlProjector:returnRet = %d\n", returnRet);
		
		MainSend(recvData->buf, packageSize, &(recvData->addr));
		
		if(act == 1) 
		{
				openProjectorNice();
		}		
		else 
		{
				closeProjector();
		}
		return 0;
	
	
}
